Hello, and welcome to this demo. This is an optional demo. In most cases, you
should be able to just go straight from
the lecture to the labs. But in case you need a
bit more hand-holding and need to see
things in action, then you may follow this demo. In this demo, we will focus on the different stages file
can be in your working area. Let's start by creating a new
file named story one TXT. I already have git repository initialized in the
story blog directory, and we're going to create a new file story one TXT
with some sample contents. Now, when a file is created
for the first time, it is always in the working
area in the untracked state. If we feel that the story
is ready to be committed, we can add the story to the staging area using
the git add command. When you now run the
git status command, we see that it is
green and it is in a state named changes
to be committed. That means it's in
a staging state. It's in the staging area, and then we commit it using
the git commit command. Now, before committing, git
needs to know who you are, because all commits are recorded by the
name of an author. You must use the Git
configure command with the user dot name and user dot email properties to set the user name and email
address of that user. When you type git commit
command without any options, GT opens a text editor, whichever is the
default text editor configured is usually
the VI editor. Here you provide as
a commit message. Every commit needs to have
a meaningful message that tells exactly what that
commit does very briefly. We go to the insert mode and we type in a message
added first story, and then we save and
quit the editor. As soon as we quit,
the changes are saved with the commit
message we provided, which can be seen here. It shows the commit message and the number of
files that were added or changed and the name of the file
that was committed. What exactly is a commit? A commit stores a copy of the
file in its current state, one file, or a set of
files that were committed. It saves a copy of
the entire file or a set of files within
the dot git folder. Our work is now safe. Even if the file
gets corrupted or we made some changes to it that
we were not supposed to, we can restore the saved
or committed version of the file later. How exactly does it save, and in what format does it save. All of that we will
discuss towards the end of this course in a lecture
named understanding git. For now, just know that
with each commit get internally stores a copy of all the files
that were committed. Now, if we run the
git status command, we see that the
working area is clean. The next time the
file is modified, it moves into a modified state. The previous version of file, which was committed is still as is in the previous
commit history. It is the current
version of the file that's now in a modified state. If this change was accidental, then we could restore the previous version
of the file from the previous commit by running the git restore command
as it is shown here. When you do that, the current
version of the file is updated with the contents of the file from the
previous commit. Now, since there are
no changes between the current and the
previous commit now, the working area is
now clean again. Now, let's say we knowingly
updated the file, and then we are ready to commit the changes
again and this time, we follow the same process
of staging the file using the Git add command and then committing it using the
Git commit command. However, this time, we
will use the option Git commit to pass in
the commit message. This way, we can
avoid going into the text editor and then
typing in the message, and then coming out
of the text editor. We will save with the
message updated first story, and now GT creates a
new commit and stores a new copy of the
current version of the story in that commit. The previous version we
committed earlier and the current version of the file lives in gits commit
history forever, allowing us to go
back in time to any previous date or commit and look at the
story at that time. Now, let's say we modify Story
1 dot TXT like last time, but we also added a
new story 2 dot TXT. If we check the status now, we see that story2.txt is in an untracked state as expected and story1.txt is in
a modified state. If we wish to, we could stage
and commit them together. Running the git add.command will stage both of
these files at once, and then running the
git commit command, we'll commit both of
these files in git. Our new commit now has a copy of both the
files we committed. In large projects, a single commit may
have many such files, and git would store a copy of all the files changed
on that commit. Now that's okay if
all the changes were made as part of
the same requirement. For example, if multiple
files were changed as part of a bug fix or
feature ad operation, then this is completely okay. In this example, if both of
these stories we're part of a single series of story and say we are adding a
character to the story, who should also be part
of the second story, then those are a related change. They should be part
of the same commit. However, say these stories
were completely independent. They are not related, and these should be
separate commits. Let's go back to the
previous state where story2 was added and
story1 was updated. In this case, we have two
files in our working area. We don't have to
commit them together. That's why we have
the staging area to allow us to stage them
separately and commit them. Remember, only files in the
staging area are committed. We could first just
state story1.txt alone and then commit it with a message updated first story, and then we could state
story2 and then commit that separately as story2.txt. Why is it important to commit separate
changes separately? One of the best practice
to be followed while committing is to make
each commit atomic. Meaning each commit
should be to solve a single problem or implement a specific
feature or improvement. Each commit should have
a single set of change. Now, it doesn't
mean a single file, it could be multiple files, but it be solving a
single set of change. This example, we can see that Sarah added a front page and Max fixed buttons in navigation
and Tej added a subtitle. These are good because all of
their commits do one thing. However, take a look
at this example. This is a bad example because each commit has multiple
sets of changes made. Sarah added the front page
and also fixed a bug. But what bug does it have anything to do
with the front page? Max fixed buttons in
the navigation bar, and also added a subtitle. The buttons in the
navigation bar and the subtitle have nothing
to do with each other. They shouldn't be part
of the same commit. Tej fixed a few bugs and
made minor improvements? What bugs and what improvements? Max made two commits
to solve the same bug? That's a bad practice too. A commit was made to update the JavaScript file
to fix a button bug and another commit
was made to update the CSS file to
fix the same bug. They're both related
to the same issue, and so they should have been
part of a single commit. Why is it important to follow this best practice
and to be atomic? One advantage is
that it maintains a clean history for the project
and one that makes sense. While working with a large team, you'll have thousands of developers and hundreds
of frequent commits. You can read the commit
history and figure out exactly what that
commit was for. Another advantage
is that git being a version control
system allows you to go back in time and revert
a particular commit. For instance, Sarah realized
that the subtitle added by Tej resulted in a
new bug on the website, and we can easily
revert that commit alone and restore the
state of the website. How to do that. We'll discuss that in one of the
upcoming lectures. But for now, I just know that that is a possibility with git. However, in the other example, if we tried to revert the
commit that added the subtitle, we would also be
reverting the fixes applied on the button
in the navigation bar. But we do not want to
revert those changes, we only want to revert the
change on the subtitle. It's always recommended to keep your commits atomic and name your commits with a message that tells exactly what
that commit does. Now, let's say we add a
new line 4 to story 1, and as expected, it's
now in a modified state. Then we stage that using
the Git add command and we can see that it is
now staged for commit. Now, before committing, let's say we make another
change to the file, say we accidentally overrode
the contents of the file. Now, if you check
the status now, we see that story 1 is staged and also modified. Why is that? Why is the same file in
two different stages? Well, when you stage
a file in Git, it caches the state of
file when it was staged, meaning even before we commit a file where we know an entire
copy of the file is saved. As soon as a file is staged, a copy of the file is
preserved or cached as well. As soon as you stage
a file, you're safe. In this case, I can restore
the state of the file when it was staged using
the git restore option. Now we have restored
the file to the state that it was in when
we last staged it. Let's look at another example. Say, in the current state, we have story one in
the staging area, and we update story 2 now. Story 2 is now in a modified state while
story one is staged. So let's say we want to
stage and commit the changes to story 2 first before we
actually commit story 1. We basically need to move story one out of the
staging area and then move story two into the staging
area. How do we do that? Now, we can remove a file from the staging area using
the command given here, which is git restore
staged option. We run the git restore
story one dot TXT command with the staged option. Now, both story 1 and story
2 are in a modified state. We took story 1 out
of the staging area. Then we will now move story two to the staging area
and then commit it. By running the Git add command and the Git commit command. Now, let's look at
another use case. Let's say we add a personal
file called notes dot TXT, where we decide to
store our ideas. Now, this file is now in an untracked state
as it's a new file. Now, while staging the
modified story 1 dot TXT file, we accidentally
add the notes file as well because we ran the git. Now, if you check the
status, we see that both these files are staged, and if we do a commit now, both of these files
would be committed. However, we don't want Nodes dot TXT to be part
of the Git repository. It's a personal file
that we're going to use to store our ideas. We can remove a track file
by running the git command. Now, you must
specify a file name. In our case, it
is nodes dot TXT, and you also must specify
one of the options. Either cached or force. Now, specifying
the cached option will retain the file
in our directory, and the force option will
delete the file permanently. In this case, I've written down some ideas for the
story in my notes file, so I don't want to delete it. I want to keep the file, even if it is removed
from the gits tracking. So I will use the cached option while
removing the file from git. Now, if you see now, we're back to the previous state where the file is still
in our directory, and when we run the
Git status command, we see that it's in
an untracked state. This is good, but it's not very good because
there are chances that we might
accidentally check in this file with git and
as we just did before. So to instruct to permanently
ignore this file, we use a dot git ignore file. We add the name of the file to a new file called
dot git ignore. Now in the Git status command, we do not see the notes
dot TXT file anymore. However, we do see
the dot git ignore file because that is also a file that git
sees as a new file. It is a recommended practice
to save the dot git ignore file itself in Git so that when you share the
repository with others, the team can add commonly
ignored files to this file, such as the cache directories, log directories, build temporary
bill files, et cetera. Well, that's it for now, head over to the labs and
practice this by yourself.